<?php

include_once 'ZReader.php';
include_once 'ZTrendCollection.php';
include_once 'ZTrendItem.php';

class ZTrendTypeReader extends ZReader {
    /**
     * Generate command string
     * @return string
     */
    public function command() {
        return sprintf('trendType %s %s %s %d %s %s %s %s %s'."\r\n",
            $this->session,
            $this->begin,
            $this->end,
            $this->timeZone,
            $this->languages,
            $this->types,
            $this->excludedIds,
            $this->excludedThreadIds,
            $this->query
        );
    }
    /**
     * Parse data that receive from server to object
     * @param $callback
     * @param $state
     * @return ZTrendCollection[]
     */
    public function parse($callback, &$state)
    {
        $i              = 0;
        /** @var ZTrendCollection[] $collections */
        $collections    = Array();
        $succeed        = false;
        $count          = 0;

        /** @var int[] $lastDate */

        //Store the last date receive from server
        //this variable help us so much to fill the missing date
        $lastDate       = Array();

        //Read data while not end of file
        while (!$this->eof()) {
            //Read the first block is the length of the data
            $numBytes = $this->readNum();

            if ($numBytes >= 0 && $numBytes < 0xffffffff) {
                //Read data
                $arr[] = $this->readNum($numBytes);
                $i++;

                //Enough field
                if ($i == 3) {
                    $type       = $arr[0];
                    //Get the current date, we add the missing date from last date to this date
                    $curDate    = strtotime($arr[1]);

                    $date = new DateTime();
                    $date->setTimestamp($curDate);
                    $item = new ZTrendItem($date, $arr[2]);

                    //Check if exist the ZTrendCollection object of type $arr[0] or not, if not, just create it
                    if (!isset($collections[$type])) {
                        $collections[$type] = new ZTrendCollection();
                        $lastDate[$type]    = strtotime(substr($this->begin, 0, 8));
                    }

                    //Fill the missing date
                    while ($curDate - $lastDate[$type] > 86400) {
                        $lastDate[$type] += 86400;
                        //Insert missing date, default missing date will have zero trend
                        $date = new DateTime();
                        $date->setTimestamp($lastDate[$type]);
                        $collections[$type]->addItem(new ZTrendItem($date, 0));
                    }

                    $collections[$type]->addItem($item);
                    $lastDate[$type]    = $curDate;
                    $arr                = array();
                    $i                  = 0;
                    $count++;
                }

                //Not succeeded
                $succeed = false;
            } else if ($numBytes == 0xffffffff) {
                $succeed = true;
            }
        }

        if ($succeed) {
            //Fill missing date from the last date that received from server to the end date
            //because default server do not return zero trend date
            foreach($collections as $type=>$col) {
                $curDate        = strtotime(mb_substr($this->end, 0, 8));

                //Fill missing date
                while ($curDate - $lastDate[$type] > 86400) {
                    $lastDate[$type] += 86400;

                    //Insert missing date, default missing date will have zero trend
                    $date = new DateTime();
                    $date->setTimestamp($lastDate[$type]);
                    $col->addItem(new ZTrendItem($date, 0));
                }
            }
        }

        $state = $succeed ? ($count > 0 ? 1 : 0) : -1;

        return $collections;
    }

    /**
     * @param null  $callback   callback function when receive data
     * @return ZTrendCollection[]
     * @throws Exception
     */
    public function read($callback = null) {
        return parent::readData($callback);
    }
}

?>
